package com.test.blackwhite.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.agp.utils.TextAlignment;
import ohos.data.distributed.common.*;
import ohos.data.distributed.user.SingleKvStore;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

import java.util.Timer;
import java.util.TimerTask;

public class DoubleGameAbilitySlice extends AbilitySlice {
    private static String A = "";
    private static int difficulty = 3;
    private DirectionalLayout layout;
    private static int length;
    private static final int interval = 5;
    private static final int left = 32;
    private static final int top = 300;
    private static final int margin = 15;
    private static int length1;
    private static final int left1 = 32;
    private static final int top1 = 1350;
    private static final int margin1 = 10;
    private static int[][] grids_a;
    private static int[][] grids_b;
    private float startX;
    private float startY;
    private static Text text;
    private static int step = 0;
    private static final String STROE_ID = "data";
    private SingleKvStore singleKvStore;
    private static KvManager kvManager;
    private static String randomstrrow = "";
    private static String randomstrcolumn = "";
    private static Timer updatetimer;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);

        difficulty = intent.getIntParam("difficulty" , 3);
        A = intent.getStringParam("A");
        initDbManager();
        initialize();
        update();
    }

    public void initialize(){
        length = 1020 / difficulty - interval;
        length1 = 600 /difficulty - interval;

        layout = new DirectionalLayout(this);

        grids_a = new int[difficulty][difficulty];
        grids_b = new int[difficulty][difficulty];
        for (int row = 0; row < difficulty; row++){
            for (int column = 0; column < difficulty; column++){
                grids_a[row][column] = 0;
            }
        }

        swipeGrids();
        createGrids();
        draw();
        drawGrids();
    }

    public void drawGrids() {
        layout.setLayoutConfig((new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT)));

        Component.DrawTask task = new Component.DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                Paint paint = new Paint();

                Color backcolor = new Color(Color.rgb(151,75,49));
                paint.setColor(backcolor);
                RectFloat backrect = new RectFloat(left - margin, top - margin, length * difficulty + interval * (difficulty - 1) + left + margin, length * difficulty + interval * (difficulty - 1) + top + margin);
                canvas.drawRect(backrect, paint);

                for (int row = 0; row < difficulty; row++) {
                    for (int column = 0; column < difficulty; column++) {
                        if(grids_a[row][column] == 0){
                            paint.setColor(Color.WHITE);
                        }else if(grids_a[row][column] == 1){
                            paint.setColor(Color.BLACK);
                        }
                        RectFloat rectFloat = new RectFloat(left + column * (length + interval), top + row * (length + interval), left + length + column * (length + interval), top + length + row * (length + interval));
                        canvas.drawRect(rectFloat, paint);
                    }
                }

                paint.setColor(backcolor);
                length1 = 600 / difficulty - interval;
                RectFloat rect1 = new RectFloat(left1 - margin1, top1 - margin1, length1 * difficulty + interval * (difficulty - 1) + left1 + margin1, length1 * difficulty + interval * (difficulty - 1) + top1 + margin1);
                canvas.drawRect(rect1, paint);
                for (int row = 0; row < difficulty; row++) {
                    for (int column = 0; column < difficulty; column++) {
                        if(grids_b[row][column] == 0){
                            paint.setColor(Color.WHITE);
                        }else if(grids_b[row][column] == 1){
                            paint.setColor(Color.BLACK);
                        }
                        RectFloat rectFloat = new RectFloat(left1 + column * (length1 + interval), top1 + row * (length1 + interval), left1 + length1 + column * (length1 + interval), top1 + length1 + row * (length1 + interval));
                        canvas.drawRect(rectFloat, paint);
                    }
                }
            }
        };
        layout.addDrawTask(task);
        setUIContent(layout);
    }

    public void draw(){
        ShapeElement background = new ShapeElement();
        background.setRgbColor(new RgbColor(138,70,50));
        background.setCornerRadius(100);

        text = new Text(this);
        text.setText("step：" + step);
        text.setTextAlignment(TextAlignment.CENTER);
        text.setTextColor(Color.WHITE);
        text.setTextSize(100);
        text.setMarginTop(80);
        text.setMarginLeft(330);
        text.setPadding(40, 10, 40, 10);
        text.setBackground(background);
        layout.addComponent(text);

        Button button_back = new Button(this);
        button_back.setText("返回");
        button_back.setTextAlignment(TextAlignment.CENTER);
        button_back.setTextColor(Color.WHITE);
        button_back.setTextSize(100);
        button_back.setMarginLeft(730);
        button_back.setMarginTop(1350);
        button_back.setPadding(30, 0, 30, 0);
        button_back.setBackground(background);
        button_back.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                terminate();
            }
        });
        layout.addComponent(button_back);

        setUIContent(layout);
    }

    public void createGrids() {
        randomstrrow = "";
        randomstrcolumn = "";
        if (A.equals("a")) {
            int random_row;
            int random_column;
            int i = 0;
            while(i < difficulty * difficulty) {
                random_row = (int)Math.floor(Math.random() * difficulty);
                random_column = (int)Math.floor(Math.random() * difficulty);

                randomstrrow += random_row;
                randomstrcolumn += random_column;

                changeGrids(random_row,random_column);
                i++;
            }
            writeData_String("randomstrrow",randomstrrow);
            writeData_String("randomstrcolumn",randomstrcolumn);
        }else if(A.equals("b")){
            while (true) {
                if (queryContact_String("randomstrrow") != null && !queryContact_String("randomstrrow").isEmpty()) {
                    break;
                }
                if (queryContact_String("randomstrcolumn") != null && !queryContact_String("randomstrcolumn").isEmpty()) {
                    break;
                }
            }
            randomstrrow = queryContact_String("randomstrrow");
            randomstrcolumn = queryContact_String("randomstrcolumn");
            int random_row;
            int random_column;
            int i = 0;
            while(i < randomstrrow.length()) {
                random_row = randomstrrow.charAt(i) - '0';
                random_column = randomstrcolumn.charAt(i) - '0';
                changeGrids(random_row,random_column);
                i++;
            }
            singleKvStore.putString("randomstrrow","");
            singleKvStore.putString("randomstrcolumn","");
        }

        for (int row = 0;row < difficulty; row++) {
            for (int column = 0;column < difficulty; column++) {
                grids_b[row][column] = grids_a[row][column];
            }
        }
    }

    public void changeGrids(int i, int j){
        grids_a = zero_one(grids_a, i, j);
        grids_a = zero_one(grids_a, i + 1, j);
        grids_a = zero_one(grids_a, i - 1, j);
        grids_a = zero_one(grids_a, i, j + 1);
        grids_a = zero_one(grids_a, i, j - 1);
    }

    public void changeGrids_b(int i, int j){
        grids_b = zero_one(grids_b, i, j);
        grids_b = zero_one(grids_b, i + 1, j);
        grids_b = zero_one(grids_b, i - 1, j);
        grids_b = zero_one(grids_b, i, j + 1);
        grids_b = zero_one(grids_b, i, j - 1);
    }

    private int[][] zero_one(int[][] gri,int i,int j){
        if(0 <= i && i <= difficulty - 1 && 0 <= j && j <= difficulty - 1){
            if(gri[i][j] == 0){
                gri[i][j] = 1;
            }else if(gri[i][j] == 1){
                gri[i][j] = 0;
            }
        }

        return gri;
    }

    public void swipeGrids(){
        layout.setTouchEventListener(new Component.TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                MmiPoint point = touchEvent.getPointerScreenPosition(0);

                switch (touchEvent.getAction()) {
                    case TouchEvent.PRIMARY_POINT_DOWN:
                        startX = point.getX();
                        startY = point.getY();

                        String str_row = String.valueOf(Math.floor((startY - top - 80) / (length + interval)));
                        String str2_column = String.valueOf(Math.floor((startX - left) / (length + interval)));

                        if(!gamesuccess()){
                            int i = str_row.charAt(0)-'0';
                            int j = str2_column.charAt(0)-'0';

                            writeData_int("row"+A, i);
                            writeData_int("column"+A, j);

                            if(0 <= i && i <= difficulty - 1 && 0 <= j && j <= difficulty - 1){
                                step++;
                                text.setText("step：" + step);
                            }

                            changeGrids(str_row.charAt(0) -'0', str2_column.charAt(0) -'0');
                            drawGrids();
                        }
                        break;
                }
                return true;
            }
        });
    }

    public void update() {
        updatetimer = new Timer();
        updatetimer.schedule(new TimerTask() {
            @Override
            public void run() {
                getUITaskDispatcher().asyncDispatch(() -> {
                    if (A.equals("a")){
                        if (queryContact_int("rowb") != -1 && queryContact_int("columnb") != -1){
                            changeGrids_b(queryContact_int("rowb"),queryContact_int("columnb"));
                            writeData_int("rowb",-1);
                            writeData_int("columnb",-1);
                        }
                    }else if (A.equals("b")) {
                        if (queryContact_int("rowa") != -1 && queryContact_int("columna") != -1){
                            changeGrids_b(queryContact_int("rowa"),queryContact_int("columna"));
                            writeData_int("rowa",-1);
                            writeData_int("columna",-1);
                        }
                    }
                    drawGrids();
                });
            }
        },0,500);
    }

    public boolean gamesuccess() {
        for (int row = 0; row < difficulty; row++){
            for (int column = 0; column < difficulty; column++){
                if(grids_a[row][column] != 0){
                    return false;
                }
            }
        }

        return true;
    }

    private KvManager createManger() {
        KvManager manager = null;
        try{
            KvManagerConfig config = new KvManagerConfig(this);
            manager = KvManagerFactory.getInstance().createKvManager(config);
        } catch (KvStoreException exception) {

        }
        return manager;
    }

    private SingleKvStore createDb(KvManager kvManager) {
        SingleKvStore kvStore = null;
        try{
            Options options = new Options();
            options.setCreateIfMissing(true).setEncrypt(false).setKvStoreType(KvStoreType.SINGLE_VERSION);
            kvStore = kvManager.getKvStore(options,STROE_ID);
        } catch (KvStoreException exception) {

        }
        return kvStore;
    }

    private void subscribeDb(SingleKvStore singleKvStore) {
        class KvStoreObserveClient implements KvStoreObserver {
            @Override
            public void onChange(ChangeNotification notification) {
                if (queryContact_String("randomstrrow") != null)
                    randomstrrow = queryContact_String("randomstrrow");
                if (queryContact_String("randomstrcolumn") != null)
                    randomstrcolumn = queryContact_String("randomstrcolumn");

                if (A.equals("a")){
                    queryContact_int("rowb");
                    queryContact_int("columnb");
                }else if (A.equals("b")) {
                    queryContact_int("rowa");
                    queryContact_int("columna");
                }
            }
        }
        KvStoreObserver kvStoreObserverClient = new KvStoreObserveClient();
        singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL,kvStoreObserverClient);
    }

    private int queryContact_int(String key) {
        try {
            return singleKvStore.getInt(key);
        } catch (KvStoreException exception) {
            return -1;
        }
    }

    private String queryContact_String(String key) {
        try {
            return singleKvStore.getString(key);
        } catch (KvStoreException exception) {
            return null;
        }
    }

    private void writeData_String(String key , String value) {
        if (key == null || key.isEmpty() || value == null || value.isEmpty())
            return;
        singleKvStore.putString(key,value);
    }

    private void writeData_int(String key,int value) {
        if (key == null || key.isEmpty()) {
            return;
        }
        singleKvStore.putInt(key,value);
    }

    private void initDbManager() {
        kvManager = createManger();
        singleKvStore = createDb(kvManager);
        subscribeDb(singleKvStore);
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
